package com.test;

import org.bytedeco.ffmpeg.avcodec.AVPacket;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import static org.bytedeco.ffmpeg.global.avcodec.AV_CODEC_ID_H264;

public class CVMain {


    public static void main(String[] args) throws IOException {

        /*String srcVideo  = "F:\\迅雷下载\\aaa\\warter.mp4" ;
        FileInputStream inputStream = new FileInputStream(srcVideo);
        String m3u8Url = "http://localhost:8080/oss/upload/test.m3u8";
        String infoUrl = "http://localhost:8080/preview/test.info";
        convertMediaToM3u8ByHttp(inputStream, m3u8Url, infoUrl);*/
        long start = System.currentTimeMillis() ;
        convertToMp4("D:\\aaa\\nonghuozhongan.mkv");
        long middle = System.currentTimeMillis() ;
        //recode("D:\\aaa\\nonghuozhongan.mkv");
        long end = System.currentTimeMillis() ;
        System.out.println("convertToMp4 time:  " + (middle - start));
        System.out.println("recode time:  " + (end - middle));
    }

    /**
     * 视频转码
     */
    public static void recode(String filename) throws FrameGrabber.Exception, FrameRecorder.Exception {
        String filePath = filename;
        String ext = filePath.substring(filePath.lastIndexOf("."));
        String newFilePath = filePath.replace(ext, "_recode.mp4");
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(filePath);
        grabber.start();
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(newFilePath, grabber.getImageWidth(), grabber.getImageHeight(), grabber.getAudioChannels());
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        recorder.setFormat("mp4");
        recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
        recorder.setFrameRate(grabber.getFrameRate());

        recorder.setFrameRate(grabber.getFrameRate());
        recorder.setSampleRate(grabber.getSampleRate());
        recorder.setAudioChannels(grabber.getAudioChannels());

        int bitrate = grabber.getVideoBitrate();
        if (bitrate == 0) {
            bitrate = grabber.getAudioBitrate();
        }
        recorder.setVideoBitrate(bitrate);
        recorder.start(grabber.getFormatContext());
        AVPacket packet;
        long dts = 0;
        while ((packet = grabber.grabPacket()) != null) {
            long currentDts = packet.dts();
            if (currentDts >= dts) {
                recorder.recordPacket(packet);
            }
            dts = currentDts;
        }
        recorder.stop();
        recorder.release();
        grabber.stop();
    }

    /**
     * 转换视频文件为mp4
     * @param filename
     * @return
     */
    public static String convertToMp4(String filename) {
        FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(filename);
        String fileName = null;
        Frame captured_frame = null;
        FFmpegFrameRecorder recorder = null;
        try {
            File file = new File(filename);
            fileName = file.getAbsolutePath().substring(0, file.getAbsolutePath().indexOf(".")) + ".mp4";
            frameGrabber.start();
            recorder = new FFmpegFrameRecorder(fileName, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
            recorder.setFormat("mp4");
            recorder.setFrameRate(frameGrabber.getFrameRate());
            recorder.setSampleRate(frameGrabber.getSampleRate());

            recorder.setAudioChannels(frameGrabber.getAudioChannels());
            recorder.setFrameRate(frameGrabber.getFrameRate());
            recorder.start();
            int frames  = 1;
            while ((captured_frame = frameGrabber.grabFrame()) != null) {
                try {
                    recorder.setTimestamp(frameGrabber.getTimestamp());
                    recorder.record(captured_frame);
                } catch (Exception e) {
                }
            }
            recorder.stop();
            recorder.release();
            frameGrabber.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fileName;
    }

    /**
     * 这个方法的url地址都必须是一样的类型 同为post
     */
    public static void convertMediaToM3u8ByHttp(InputStream inputStream, String m3u8Url, String infoUrl) throws IOException {

        avutil.av_log_set_level(avutil.AV_LOG_INFO);
        FFmpegLogCallback.set();

        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputStream);
        grabber.start();

        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(m3u8Url, grabber.getImageWidth(), grabber.getImageHeight(), grabber.getAudioChannels());

        recorder.setFormat("hls");
        recorder.setOption("hls_time", "5");
        recorder.setOption("hls_list_size", "0");
        recorder.setOption("hls_flags", "delete_segments");
        recorder.setOption("hls_delete_threshold", "1");
        recorder.setOption("hls_segment_type", "mpegts");
        recorder.setOption("hls_segment_filename", "http://localhost:8080/oss/upload/test-%d.ts");
        //recorder.setOption("hls_key_info_file", infoUrl);

        // http属性
        recorder.setOption("method", "POST");

        recorder.setFrameRate(25);
        recorder.setGopSize(2 * 25);
        recorder.setVideoQuality(1.0);
        recorder.setVideoBitrate(10 * 1024);
        recorder.setVideoCodec(AV_CODEC_ID_H264);
        recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
        recorder.start();

        Frame frame;
        while ((frame = grabber.grabImage()) != null) {
            try {
                recorder.record(frame);
            } catch (FrameRecorder.Exception e) {
                e.printStackTrace();
            }
        }
        recorder.setTimestamp(grabber.getTimestamp());
        recorder.close();
        grabber.close();
    }
}
